]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
environment: Ignore animation events after shutdown
authorMarco Trevisan (Treviño) <mail@3v1n0.net>
Fri, 5 Dec 2025 22:14:29 +0000 (23:14 +0100)
committerMarco Trevisan (Treviño) <mail@3v1n0.net>
Fri, 5 Dec 2025 22:27:08 +0000 (23:27 +0100)
As soon as the shutdown starts, any animation event does not make sense,
although during this phase the clutter timelines may still proceed and
potentially calling invalid code in their callbacks.

Prevent this from happening by disconnecting from any timeline signal
we are connected to as soon as the `shutdown` signal is emitted

Co-Authored-By: Florian Müllner <fmuellner@gnome.org>
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3996>

js/ui/environment.js

index 094b95018d8c3a3f05e29103bff3e01311113617..8effcd240d8994312b2fac6b923199f70bb55290 100644 (file)
@@ -18,6 +18,8 @@ import St from 'gi://St';
 import * as SignalTracker from '../misc/signalTracker.js';
 import {adjustAnimationTime} from '../misc/animationUtils.js';
 
+const sessionSignalHolder = new SignalTracker.TransientSignalHolder();
+
 setConsoleLogDomain('GNOME Shell');
 
 Gio._promisify(Gio.DataInputStream.prototype, 'fill_async');
@@ -153,14 +155,16 @@ function _easeActor(actor, params) {
     const [transition] = transitions;
 
     if (transition && transition.delay)
-        transition.connect('started', () => prepare());
+        transition.connectObject('started', () => prepare(), sessionSignalHolder);
     else
         prepare();
 
-    if (transition)
-        transition.connect('stopped', (t, finished) => callback(finished));
-    else
+    if (transition) {
+        transition.connectObject('stopped', (t, finished) => callback(finished),
+            sessionSignalHolder);
+    } else {
         callback(true);
+    }
 }
 
 function _easeAnimatableProperty(animatable, propName, target, params) {
@@ -244,11 +248,12 @@ function _easeAnimatableProperty(animatable, propName, target, params) {
     transition.set_to(target);
 
     if (transition.delay)
-        transition.connect('started', () => prepare());
+        transition.connectObject('started', () => prepare(), sessionSignalHolder);
     else
         prepare();
 
-    transition.connect('stopped', (t, finished) => callback(finished));
+    transition.connectObject('stopped',
+        (t, finished) => callback(finished), sessionSignalHolder);
 }
 
 // Add some bindings to the global JS namespace
@@ -276,6 +281,9 @@ GObject.Object.prototype.disconnect_object = function (...args) {
 
 SignalTracker.registerDestroyableType(Clutter.Actor);
 
+global.connectObject('shutdown', () => sessionSignalHolder.destroy(),
+    sessionSignalHolder);
+
 Cairo.Context.prototype.setSourceColor = function (color) {
     const {red, green, blue, alpha} = color;
     const rgb = [red, green, blue].map(v => v / 255.0);